package ga;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Path {
	
	public static final int ZERO = 0;
	public static final int UP = 1;
	public static final int RIGHT = 2;
	public static final int DOWN = 3;
	public static final int LEFT = 4;
	
	
	private List<Point> path = new ArrayList<Point>();
	
	
	private double fitness = 0;
	private int distance = 0;
	
	
	// empty path construction
	public Path (){
		for (int i = 0; i < PathManager.getNumberOfPoints(); i++) {
			path.add(null);
		}
	}
	
	public Path(List<Point> path){
		this.path = path;
	}
	
	public Point getPoint(int pathIndex){
		return path.get(pathIndex);
	}
	
	public void generateRandomPath(){
		for (int i = 0; i < PathManager.getNumberOfPoints(); i++) {
			setPoint(i, PathManager.getPointByIndex(i));
		}
		Collections.shuffle(path);
	}

	public void setPoint(int pathIndex, Point pointToAdd) {
		path.set(pathIndex, pointToAdd);
		fitness = 0;
		distance = 0;
	}
	
	
	public double getFitness(){
		if(fitness == 0){
			return 1.0/getDistance();
		}
		return fitness;
	}

	public int getDistance() {
		if (distance == 0){
			int pathDistance = 0;
			
			for (int i = 0; i < path.size(); i++) {
				Point fromPoint = getPoint(i);
                // City we're travelling to
                Point destinationPoint;
                // Check we're not on our tour's last city, if we are set our
                // tour's final destination city to our starting city
                if(i+1 < path.size()){
                    destinationPoint = getPoint(i+1);
                }
                else{
                    destinationPoint = getPoint(0);
                }
                // Get the distance between the two cities
                pathDistance += fromPoint.distanceTo(destinationPoint);
			}
			distance = pathDistance;
		}
		return distance;
	}
	
	
	public boolean containsPoint(Point p){
		return path.contains(p);
	}
	
	public List<Point> getPath(){
		return path;
	}
	
	@Override
	public String toString() {
		return "Path [path=" + path + "]";
	}

	public double pathSize() {
		return path.size();
	}
	
	
}
